package com.jymj.service.impl;

import com.jymj.dao.RenovatedDao;
import com.jymj.dao.YlDao;
import com.jymj.entity.*;
import com.jymj.entity.dto.RenovatedDto;
import com.jymj.entity.dto.RenovatedRejectedDto;
import com.jymj.entity.model.PointAndTypeEntity;
import com.jymj.entity.vo.StatisticalEntity;
import com.jymj.service.RenovatedService;
import com.jymj.utils.RRException;
import com.jymj.utils.ShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by ${lc} on 2021/6/16.
 */
@Service
public class RenovatedServiceImpl implements RenovatedService {
    @Autowired
    private RenovatedDao renovatedDao;
    @Autowired
    private YlDao ylDao;

    @Value("${image.renovated_file.dirPath}")
    private String dirPath;
    @Value("${image.renovated_file.urlPath}")
    private String urlPath;


    @Override
    public List<StatisticalEntity> getStatistical(String date) {
        List<StatisticalEntity> statistical = renovatedDao.getStatistical(date, ShiroUtils.getUserEntity());
        StatisticalEntity statisticalEntity = new StatisticalEntity();
        statisticalEntity.setXzqmc("总计");
        Long xccount = 0L;//巡查数
        Long zgcount = 0L;//整改数
        Long dclcount = 0L;//待处理数
        Long shcount = 0L;//审核数
        Long xzcount = 0L;//销账数
        Long yqcount = 0L;//逾期数
        Long counts = 0L;//4--->3 驳回次数
        Long amount = 0L;//总数
        for (StatisticalEntity entity : statistical) {
            xccount = xccount+(entity.getXccount() == null ? 0L :entity.getXccount());
            zgcount = zgcount+(entity.getZgcount() == null ? 0L :entity.getZgcount());
            dclcount = dclcount+(entity.getDclcount() == null ? 0L :entity.getDclcount());
            shcount = shcount+(entity.getShcount() == null ? 0L :entity.getShcount());
            xzcount = xzcount+(entity.getXzcount() == null ? 0L :entity.getXzcount());
            yqcount = yqcount+(entity.getYqcount() == null ? 0L :entity.getYqcount());
            counts = counts+(entity.getCounts() == null ? 0L :entity.getCounts());
            amount = amount+(entity.getAmount() == null ? 0L :entity.getAmount());
        }
        statisticalEntity.setXccount(xccount);
        statisticalEntity.setZgcount(zgcount);
        statisticalEntity.setDclcount(dclcount);
        statisticalEntity.setShcount(shcount);
        statisticalEntity.setXzcount(xzcount);
        statisticalEntity.setYqcount(yqcount);
        statisticalEntity.setCounts(counts);
        statisticalEntity.setAmount(amount);
        statistical.add(0,statisticalEntity);
        return statistical;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public RenovatedFile uploadFile(MultipartFile file) {
        RenovatedFile renovatedFile = new RenovatedFile();
        SysUserEntity userEntity = ShiroUtils.getUserEntity();
        File genPath = null;
        try {
            genPath = new File(ResourceUtils.getURL("classpath:").getPath());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RRException("获取文件路径失败 请联系管理员" + e.getMessage());
        }
        if (!genPath.exists()) {
            genPath = new File("");
        }
        //在开发测试模式时，得到地址为：{项目跟目录}/target/progress/
        //在打成jar正式发布时，得到的地址为:{发布jar包目录}/progress/
        File savePath = new File(genPath.getAbsolutePath(), "fileupload" + File.separator + dirPath);

        //1.校验图片类型是否正确 jpg|png|gifxxxx  1.正则表达式判断  2.准备集合之后进行校验Set<去重>
        //1.1 获取上传的图片类型 ABC.JPG
        String fileName = file.getOriginalFilename();  //文件的全名 abc.jpg
        fileName = fileName.toLowerCase();                   //将所有的字符转化为小写
        int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);  //含头不含尾

        //2.上传的数据是否为恶意程序. 高度和宽度是否为null. 利用图片API
        //BufferedImage对象 专门负责封装图片
        try {
            //3.采用分目录存储的方式  a.jpg
            //3.1 分目录存储方式1 hash方式 ACBBCDD
            //3.1 分目录存储方式2 时间方式存储 yyyy/MM/dd
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
            //3.2 准备文件存储的目录
            String imageDir = savePath.getParent() + File.separator + dirPath + dateDir;
            File fileDir = new File(imageDir);
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }

            //4 实现文件上传
            //4.1 动态拼接文件名称   uuid.后缀  f3aa1378-ece6-11ea-98c9-00d861eaf238
            String uuid =
                    UUID.randomUUID().toString().replace("-", "");
            String realFileName = uuid + fileType;
            //4.2 准备文件上传的全路径  磁盘路径地址+文件名称
            File imageFile = new File(imageDir + realFileName);
            //4.3 实现文件上传
            file.transferTo(imageFile);
            //5.动态生成URL地址
            //请求协议: http://  https:// 带证书的网址 安全性更高 公钥私钥进行加密解密.
            //向服务器运行商购买域名  com  cn  org   hosts文件
            //图片存储的虚拟地址的路径 动态变化的路径
            String url = urlPath + dateDir + realFileName;
            renovatedFile.setName(fileName)
                    .setPath(imageDir + realFileName)
                    .setUrl(url)
                    .setEnpsn(userEntity.getUserId())
                    .setEntime(new Date())
                    .setJlrname(userEntity.getName())
                    .setJlrtel(userEntity.getMobile())
                    .setMsid(-1L);
            renovatedDao.saveFile(renovatedFile);
            return renovatedFile.setPath(null);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RRException("图片上传失败");
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void saveOrUpdate(RenovatedDto renovatedDto) {
        renovatedDto.setUpdateTime(new Date());
        SysUserEntity userEntity = ShiroUtils.getUserEntity();
        if (renovatedDto.getId() == null) {
            renovatedDto.setJlr(userEntity.getName())
                    .setJltime(new Date())
                    .setUserId(userEntity.getUserId())
                    .setCreatedTime(new Date())
                    .setUpdateUser(userEntity.getName())
                    .setUpdateUserId(userEntity.getUserId());
            renovatedDao.saveRenovated(renovatedDto);
            List<RenovatedDto> renovated = renovatedDao.getRenovated(renovatedDto.getYlId(), null, null,null);
            if (renovated.size() > 1) throw new RRException("改点位已存在翻建信息，请勿重复添加");
            renovatedDto.setUpdateUser(userEntity.getName())
                    .setUpdateUserId(userEntity.getUserId());
            renovatedDao.updatefj(renovatedDto.getYlId());
        } else {
            if (renovatedDto.getQutype() == 2){
                renovatedDto.setXftime(new Date());
            }else if (renovatedDto.getQutype() == 3){
                renovatedDto.setZgr(userEntity.getName())
                        .setZgphone(userEntity.getMobile())
                        .setZgtime(new Date());
            }else if (renovatedDto.getQutype() == 4){
                renovatedDto.setClr(userEntity.getName())
                        .setCltime(new Date())
                        .setClphone(userEntity.getMobile());
            }else if (renovatedDto.getQutype() == 5){
                renovatedDto.setShname(userEntity.getName())
                        .setShphone(userEntity.getMobile())
                        .setShtime(new Date());
            }
            //驳回
            if (renovatedDto.getQutype() == 100){
                RenovatedDto renovatedDto1 = renovatedDao.queryById(renovatedDto.getId());
                RenovatedRejectedDto renovatedRejectedDto = new RenovatedRejectedDto();
                renovatedRejectedDto.setClr(renovatedDto1.getClr());
                renovatedRejectedDto.setClbz(renovatedDto1.getClbz());
                renovatedRejectedDto.setClphone(renovatedDto1.getClphone());
                renovatedRejectedDto.setCltime(renovatedDto1.getCltime());
                renovatedRejectedDto.setBhr(userEntity.getName());
                renovatedRejectedDto.setBhtel(userEntity.getMobile());
                renovatedRejectedDto.setBhtime(new Date());
                renovatedRejectedDto.setBhbz(renovatedDto.getShbz());
                renovatedRejectedDto.setYlId(renovatedDto.getYlId());
                renovatedRejectedDto.setEsid(renovatedDto.getId());
                renovatedRejectedDto.setType(1L);
                //添加到驳回信息 并将翻建处理人信息清空并将图片转成驳回图片
                renovatedDao.saveRejcted(renovatedRejectedDto);
                renovatedDao.updateClrInfo(renovatedDto.getId());
                renovatedDao.updateFile(renovatedDto.getId(),renovatedRejectedDto.getId());
            }else {
                int rows = renovatedDao.updateRenovated(renovatedDto);
                if (rows == 0) throw new RRException("修改的内容不存在");
            }
        }
        if (renovatedDto.getRenovatedFiles().size() > 0) {
            renovatedDao.updateRenovatedFile(renovatedDto);
        }
    }

    @Override
    @Transactional(rollbackFor = RRException.class)
    public void deleteFile(Long[] ids) {
        if (ids == null || ids.length <= 0) {
            throw new RRException("ids不能为空");
        }
        List<RenovatedFile> files = renovatedDao.getFiles(ids, null);
        if (files.size() < 1) throw new RRException("删除的文件可能已经不存在");
        files.forEach(file -> new File(file.getPath()).delete());
        renovatedDao.deletefileById(ids);
    }

    @Override
    @Transactional(rollbackFor = RRException.class)
    public void deleteRenovated(RenovatedDto renovatedDto) {
        if (renovatedDto.getId() == null)
            throw new RRException("至少选择一项");
        List<RenovatedFile> files = renovatedDao.getFiles(null, renovatedDto.getId());
        if (files.size() > 0) {
            Long[] ids = files.stream().map(RenovatedFile::getId).collect(Collectors.toList()).toArray(new Long[0]);
            deleteFile(ids);
        }
        renovatedDao.deleteRenovated(renovatedDto);
    }

    @Override
    public RenovatedDto getRenovated(String point) {
        YlEntity ylEntity = ylDao.queryByPoint(point, null);
        if (ylEntity == null) {
            throw new RRException("点位超出范围");
        }
        List<RenovatedDto> renovated = renovatedDao.getRenovated(ylEntity.getObjectid().longValue(), null, null,null);
        if (renovated.size() == 0) {
            return new RenovatedDto().setYlEntity(ylEntity);
        }
        RenovatedDto renovatedDto = renovated.get(0);
        renovatedDto.setYlEntity(ylEntity);
        renovatedDto.setRenovatedFiles(renovatedDao.getFiles(null, renovatedDto.getId())
                .stream().map(renovatedFile -> renovatedFile.setPath(null)).collect(Collectors.toList()));
        renovatedDto.setRenovatedRejectedDtos(renovatedDao.getRenovatedRejected( renovatedDto.getId()));
        return renovatedDto;
    }

    @Override
    public List<RenovatedDto> getRenovatedList(String code, String xzqmc, Long userId, Long id,Integer qutype) {
        List<RenovatedDto> renovatedDtos = new ArrayList<>();
        List<YlEntity> yls = renovatedDao.getylsList(code, xzqmc);
        for (YlEntity yl : yls) {
            RenovatedDto renovatedDto = renovatedDao.getRenovated(yl.getObjectid().longValue(), userId, id,qutype).size() == 0 ? null :
                    renovatedDao.getRenovated(yl.getObjectid().longValue(), userId, id,qutype).get(0);
            if (renovatedDto != null) {
                renovatedDto.setRenovatedFiles(renovatedDao.getFiles(null, renovatedDto.getId())
                        .stream().map(renovatedFile -> renovatedFile.setPath(null)).collect(Collectors.toList()));
                renovatedDto.setYlEntity(yl);
                renovatedDtos.add(renovatedDto);
            }
        }
        renovatedDtos.sort(Comparator.comparing(RenovatedDto::getUpdateTime).reversed());
        return renovatedDtos;
    }

    @Override
    public List<Renovated> queryList(RenovatedDto renovatedDto) {
        return renovatedDao.queryList(renovatedDto);
    }

    @Override
    public RenovatedDto queryInfo(Long id) {
        RenovatedDto renovatedDto = renovatedDao.queryById(id);
        renovatedDto.setYlEntity(ylDao.queryByGid(renovatedDto.getYlId()));
        renovatedDto.setRenovatedFiles(renovatedDao.getFiles(null,id));
        renovatedDto.setRenovatedRejectedDtos(renovatedDao.getRenovatedRejected(id));
        return renovatedDto;
    }

    @Override
    public KeyValueEntity getSteps(RenovatedDto renovatedDto) {
        return renovatedDao.getSteps(renovatedDto);
    }

    @Override
    public List<KeyValueEntity> getRenovatedByxy(PointAndTypeEntity pointAndTypeEntity) {
        if (pointAndTypeEntity.getType() == 4) {
            if (pointAndTypeEntity.getType() == null
                    || pointAndTypeEntity.getXmax() == null
                    || pointAndTypeEntity.getXmin() == null
                    || pointAndTypeEntity.getYmax() == null) {
                throw new RRException("参数错误");
            }
        }
        if (pointAndTypeEntity.getType() == 1) {
            return renovatedDao.getRenovatedByxy1(pointAndTypeEntity);
        } else if (pointAndTypeEntity.getType() == 2) {
            return renovatedDao.getRenovatedByxy2(pointAndTypeEntity);
        } else if (pointAndTypeEntity.getType() == 3) {
            return renovatedDao.getRenovatedByxy3(pointAndTypeEntity);
        }
        throw new RRException("type超出规定范围");
    }


}
